package com.zhanghe.security.util;

import com.google.gson.Gson;
import com.zhanghe.security.util.auth2.Oauth2Token;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.json.GsonJsonParser;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class HttpClientUtil {

    protected static final Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);

    private static final CloseableHttpClient CLIENT = newInstance();

    public static CloseableHttpClient newInstance() {
        try {
            SSLContext sslContext = SSLContext.getInstance("TLS");
            X509TrustManager tm = new X509TrustManager() {
                @Override
                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }

                @Override
                public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }

                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
            };
            sslContext.init(null, new TrustManager[] { tm }, null);

            RequestConfig globalConfig = RequestConfig.custom()
                    .setCookieSpec(CookieSpecs.STANDARD)
                    .build();
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new String[] { "TLSv1","TLSv1.2","SSLv2Hello" },
                    null, SSLConnectionSocketFactory.getDefaultHostnameVerifier());
            return HttpClients.custom().setSSLSocketFactory(sslsf).setDefaultRequestConfig(globalConfig).build();
        }catch (NoSuchAlgorithmException e){

        }catch (KeyManagementException e){

        }
        return null;
    }

    public static <T> T get(String url,Class<T> classes){
        List<RequestHeader> list = new ArrayList<>();
        list.add(new RequestHeader("Accept","application/json"));
        String json = get(url,null,STRING_RESULT,list);
        GsonJsonParser parser = new GsonJsonParser();
        Gson gs = new Gson();
        T res = gs.fromJson(json,classes);
        return res;
    }

    /**
     *
     * @return
     */
    public static String get(String url, List<NameValuePair> params, ResponseHandler<String> handler,List<RequestHeader> headers){
        HttpGet get = new HttpGet(url);
        for(RequestHeader header:headers){
            get.setHeader(header.getHeader(),header.getValue());
        }
        try {
            return CLIENT.execute(get, handler);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    /**
     *
     * @return
     */
    public static String post(String url, List<NameValuePair> params, ResponseHandler<String> handler,List<RequestHeader> headers ){
        HttpPost post = new HttpPost(url);
        for(RequestHeader header:headers){
            post.setHeader(header.getHeader(),header.getValue());
        }
        post.setHeader("Accept","application/json");
        if (params != null && !params.isEmpty()) {
            post.setEntity(new UrlEncodedFormEntity(params, StandardCharsets.UTF_8));
        }
        try {
            return CLIENT.execute(post, handler);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static final ResponseHandler<String> STRING_RESULT = new ResponseHandler<String>() {
        private static final String DEFAULT_CHARSET = "utf-8";
        private static final int HTTP_OK = 200;

        @Override
        public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != HTTP_OK) {
                logger.debug("请求的响应状态码为[{}]",statusCode);
            }
            HttpEntity entity = response.getEntity();
            return EntityUtils.toString(entity, DEFAULT_CHARSET);
        }
    };


    public static void main(String[] args) {
        List<RequestHeader> list = new ArrayList<>();
        list.add(new RequestHeader("Accept","application/json"));
        String res = post("https://github.com/login/oauth/access_token?client_id=9304cb97ee37d73f175c&client_secret=3beebc040dfa8234e59883d67106f60cca83a090&code=07fa67220ddf0cb99394",null,STRING_RESULT,list);
//        Oauth2Token token = get("https://github.com/login/oauth/access_token?client_id=9304cb97ee37d73f175c&client_secret=3beebc040dfa8234e59883d67106f60cca83a090&code=07fa67220ddf0cb99394",Oauth2Token.class);
//        System.out.println(token);
        System.out.println(res);
    }
}
